package com.credithc.signature.common.utils;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.List;

/**
 * 描 述:上传文件到S3<br/>
 * 作 者: hujingbo<br/>
 * 创 建：2019/1/21 10:26<br/>
 * 版 本：v1.0.0<br>
 * <p>
 * 历 史: (版本) 作者 时间 注释 <br/>
 */
@Slf4j
@Component
public class AmazonUtil2 {

    //---------------------------eip----------------------------

    private static String EIP_AMAZON_AWS_ACCESS_KEY = "HNC107CPYYW6PGRXY2VA";
    private static String EIP_AMAZON_AWS_SECRET_KEY = "oXjFz9nKT4oW2dt4D1jqKeLDcBTMyRnJDgJMTHWh";
    private static String EIP_AMAZON_AWS_BUCKET = "hetongxitong";
    private static String EIP_AMAZON_ENDPOINT_URL = "http://test-internal-rgw.cloud.hcinner";

    @Value("${aws.eip.access.key:HNC107CPYYW6PGRXY2VA}")
    public void setEipAmazonAwsAccessKey(String eipAmazonAwsAccessKey) {
        EIP_AMAZON_AWS_ACCESS_KEY = eipAmazonAwsAccessKey;
    }

    @Value("${aws.eip.secret.key:oXjFz9nKT4oW2dt4D1jqKeLDcBTMyRnJDgJMTHWh}")
    public void setEipAmazonAwsSecretKey(String eipAmazonAwsSecretKey) {
        EIP_AMAZON_AWS_SECRET_KEY = eipAmazonAwsSecretKey;
    }

    @Value("${aws.eip.s3.bucket:hetongxitong}")
    public void setEipAmazonAwsBucket(String eipAmazonAwsBucket) {
        EIP_AMAZON_AWS_BUCKET = eipAmazonAwsBucket;
    }

    @Value("${aws.eip.s3.endpoint:http://test-internal-rgw.cloud.hcinner}")
    public void setEipAmazonEndpointUrl(String eipAmazonEndpointUrl) {
        EIP_AMAZON_ENDPOINT_URL = eipAmazonEndpointUrl;
    }

    /**
     * 初始化连接，每次使用需要重新连接
     */
    private static AmazonS3 initSecondAmazonS3() {
        AWSCredentials credentials = new BasicAWSCredentials(EIP_AMAZON_AWS_ACCESS_KEY, EIP_AMAZON_AWS_SECRET_KEY);
        ClientConfiguration clientConfig = new ClientConfiguration();
        clientConfig.setProtocol(Protocol.HTTP);
        AmazonS3 s3SecondClient = new AmazonS3Client(credentials, clientConfig);
        s3SecondClient.setEndpoint(EIP_AMAZON_ENDPOINT_URL);
        return s3SecondClient;
    }


    /**
     * 上传文件
     *
     * @param tempFile       待上传文件
     * @param remoteFileName 文件名
     * @return
     */
    public static boolean uploadToS3(File tempFile, String remoteFileName) {
        try {
            AmazonS3 s3 = initSecondAmazonS3();
            if (!s3.doesBucketExistV2(EIP_AMAZON_AWS_BUCKET)) {
                s3.createBucket(EIP_AMAZON_AWS_BUCKET);
            }
            s3.putObject(new PutObjectRequest(EIP_AMAZON_AWS_BUCKET, remoteFileName, tempFile).withCannedAcl(CannedAccessControlList.BucketOwnerFullControl));
            return true;
        } catch (Exception e) {
            log.error("AmazonS3 上传文件[File模式]发生异常 ", e);
        }
        return false;
    }

    /**
     * 上传文件
     *
     * @param multipartFile  待上传文件
     * @param remoteFileName 文件名
     * @return
     */
    public static boolean uploadToS3(CommonsMultipartFile multipartFile, String remoteFileName) {
        InputStream in = null;
        try {
            AmazonS3 s3 = initSecondAmazonS3();
            in = multipartFile.getInputStream();
            FileItem fileItem = multipartFile.getFileItem();

            if (!s3.doesBucketExistV2(EIP_AMAZON_AWS_BUCKET)) {
                s3.createBucket(EIP_AMAZON_AWS_BUCKET);
            }

            ObjectMetadata omd = new ObjectMetadata();
            omd.setContentType(fileItem.getContentType());
            omd.setContentLength(fileItem.getSize());
            omd.setHeader("filename", fileItem.getName());
            s3.putObject(new PutObjectRequest(EIP_AMAZON_AWS_BUCKET, remoteFileName, in, omd).withCannedAcl(CannedAccessControlList.BucketOwnerFullControl));
            return true;
        } catch (Exception e) {
            log.error("AmazonS3 上传文件[InputStream模式]发生异常 ", e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error("AmazonS3 上传文件[关闭InputStream流]发生异常 ", e);
                }
            }
        }
        return false;
    }

    /**
     * 下载文件
     *
     * @param remoteFileName 文件名
     * @return
     */
    public static InputStream downFromS3(String remoteFileName) {
        try {
            AmazonS3 s3 = initSecondAmazonS3();
            GetObjectRequest request = new GetObjectRequest(EIP_AMAZON_AWS_BUCKET, remoteFileName);
            S3Object object = s3.getObject(request);
            InputStream input = object.getObjectContent();
            log.info("AmazonS3 下载文件成功......");
            return input;
        } catch (Exception e) {
            log.error("AmazonS3 下载文件发生异常 ", e);
        }
        return null;
    }

    /**
     * 下载文件
     *
     * @param remoteFileName 文件名
     * @param path           下载路径
     */
    public static boolean downFromS3(String remoteFileName, String path) throws Exception {
        try {
            AmazonS3 s3 = initSecondAmazonS3();
            GetObjectRequest request = new GetObjectRequest(EIP_AMAZON_AWS_BUCKET, remoteFileName);
            s3.getObject(request, new File(path));
            return true;
        } catch (Exception e) {
            log.error("AmazonS3 下载文件发生异常 ", e);
            throw new Exception("AmazonS3 下载文件发生异常 ");
        }
    }

    /**
     * 删除文件
     *
     * @param remoteFileName 待删除文件名
     * @throws IOException
     */
    public static void delFromS3(String remoteFileName) {
        try {
            AmazonS3 s3 = initSecondAmazonS3();
            s3.deleteObject(EIP_AMAZON_AWS_BUCKET, remoteFileName);
            log.error("AmazonS3 删除文件成功......");
        } catch (Exception e) {
            log.error("AmazonS3 删除文件发生异常 ", e);
        }
    }

    /**
     * 获取短链接 带过期时间
     *
     * @param remoteFileName 文件名称
     * @param expiration     过期时间/秒
     */
    public static String getUrlFromS3(String remoteFileName, int expiration) {
        try {
            AmazonS3 s3 = initSecondAmazonS3();
            GeneratePresignedUrlRequest httpRequest = new GeneratePresignedUrlRequest(EIP_AMAZON_AWS_BUCKET, remoteFileName);
            httpRequest.setExpiration(new Date(System.currentTimeMillis() + expiration * 1000));
            URL url = s3.generatePresignedUrl(httpRequest);
            return String.valueOf(url);
        } catch (Exception e) {
            log.error("AmazonS3获取临时链接异常 ", e);
        }
        return null;
    }

    /**
     * 获取永久链接
     *
     * @param remoteFileName 文件名称
     */
    public static String getUrlFromS3(String remoteFileName) {
        String url = "";
        try {
            AmazonS3 s3 = initSecondAmazonS3();
            GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(EIP_AMAZON_AWS_BUCKET, remoteFileName);
            url = String.valueOf(s3.generatePresignedUrl(urlRequest)).split("\\?")[0];
            if (url.indexOf(remoteFileName) == -1) {
                throw new RuntimeException("url文件名称校验不合法");
            }
            return url;
        } catch (Exception e) {
            log.error("AmazonS3 获取永久链接发生异常 ", e);
            return "";
        }
    }

    /**
     * 根据桶名称获取文件集合
     */
    public static List<S3ObjectSummary> getFileLists() {
        AmazonS3 s3 = initSecondAmazonS3();
        ObjectListing objectListing = s3.listObjects(EIP_AMAZON_AWS_BUCKET);
        List<S3ObjectSummary> objectSummaries = objectListing.getObjectSummaries();
        return objectSummaries;
    }

    /**
     * 测试用例
     *
     * @param args
     */
    public static void main(String[] args) {
        // 1.上传文件
//        File file = new File("D:\\test.pdf");
//        boolean test = uploadToS3(file, "test");
//        System.out.println(test);

        // 2.获取文件链接
//        String test1 = getUrlFromS3("test");
//        String test2 = getUrlFromS3("test", 30);
//        System.out.println(test1);
//        System.out.println(test2);

        // 3.下载文件
//        boolean b = downFromS3("test", "D:\\48464646.pdf");
//        System.out.println(b);

//        InputStream input = downFromS3("test");
//        try {
//            File file = new File("D:\\78945.pdf");
//            FileOutputStream fileOutputStream = new FileOutputStream (file);
//            int len = 0;
//            byte[] data = new byte[input.available()];
//            while ((len = input.read(data)) != -1) {
//                fileOutputStream.write(data, 0, len);
//            }
//            fileOutputStream.close();
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        // 4.删除文件
//        delFromS3("test");
    }
}

